#include "DX11InputManager.h"
#include "DX11ErrorReport.h"

#include "Timer.h"

DX11InputManager::DX11InputManager()
{
	m_directInput = nullptr;
	m_keyboardDevice = nullptr;
	m_mouseDevice = nullptr;

	m_currentKey = -1;
	m_pollRate = 0.02f;
	m_timer = 0.0f;	

	m_takingKeyboardInput = true;
}

DX11InputManager::~DX11InputManager()
{
	if (m_mouseDevice)
	{
		m_mouseDevice->Unacquire();
		m_mouseDevice->Release();
		m_mouseDevice = 0;
	}

	if (m_keyboardDevice)
	{
		m_keyboardDevice->Unacquire();
		m_keyboardDevice->Release();
		m_keyboardDevice = 0;
	}
	
	if (m_directInput)
	{
		m_directInput->Release();
		m_directInput = 0;
	}
}

bool DX11InputManager::Init(HINSTANCE hInstance, HWND hWnd, int screenWidth, int screenHeight)
{
	HRESULT result = S_OK;

	m_screenWidth = screenWidth;
	m_screenHeight = screenHeight;

	m_mouseX = 0;
	m_mouseY = 0;

	result = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_directInput, NULL);
	if (FAILED(result))
	{
		return false;
	}

	// init keyboard
	result = m_directInput->CreateDevice(GUID_SysKeyboard, &m_keyboardDevice, NULL);
	if (FAILED(result))
	{
		return false;
	}

	result = m_keyboardDevice->SetDataFormat(&c_dfDIKeyboard);
	if (FAILED(result))
	{
		return false;
	}
		
	result = m_keyboardDevice->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
	if (FAILED(result))
	{
		return false;
	}

	//result = m_keyboardDevice->Acquire();
	//if (FAILED(result))
	//{
	//	return false;
	//}

	// init mouse

	result = m_directInput->CreateDevice(GUID_SysMouse, &m_mouseDevice, NULL);
	if (FAILED(result))
	{
		return false;
	}

	result = m_mouseDevice->SetDataFormat(&c_dfDIMouse);
	if (FAILED(result))
	{
		return false;
	}

	result = m_mouseDevice->SetCooperativeLevel(hWnd, DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if (FAILED(result))
	{
		return false;
	}

	result = m_mouseDevice->Acquire();
	if (FAILED(result))
	{
		return false;
	}
	
	return true;
}

bool DX11InputManager::Update()
{
	// checks what key/mouse has been input this frame
	bool result;

	result = ReadKeyboard();
	if(!result)
	{
		return false;
	}

	result = ReadMouse();
	if (!result)
	{
		return false;
	}

	ProcessInput();

	return true;
}

bool DX11InputManager::ReadKeyboard()
{
	HRESULT result;

	result = m_keyboardDevice->GetDeviceState(sizeof(m_keyboardState), (LPVOID)&m_keyboardState);
	if(FAILED(result))
	{
		if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
		{
			m_keyboardDevice->Acquire();
		}
		else
		{
			return false;
		}
	}
		
	return true;
}

bool DX11InputManager::ReadMouse()
{	
	HRESULT result;

	result = m_mouseDevice->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouseState);
	if(FAILED(result))
	{
		if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
		{
			m_mouseDevice->Acquire();
		}
		else
		{
			return false;
		}
	}

	return true;
}

void DX11InputManager::ProcessInput()
{
	m_mouseX = m_mouseState.lX;
	m_mouseY = m_mouseState.lY;

	if (m_mouseX > m_screenWidth)
	{
		m_mouseX = m_screenWidth;
	}
	if (m_mouseY > m_screenHeight)
	{
		m_mouseY = m_screenHeight;
	}
	
	if (m_mouseX < 0)
	{
		m_mouseX = 0;
	}
	if (m_mouseY < 0)
	{
		m_mouseY = 0;
	}
}

void DX11InputManager::GetMouseLocation(int& mouseX, int& mouseY)
{
	mouseX = m_mouseX;
	mouseY = m_mouseY;
}

void DX11InputManager::GetMouseLocation(D3DXVECTOR2* pos)
{
	pos->x = float(m_mouseX);
	pos->y = float(m_mouseY);
}

//unsigned char* DX11InputManager::GetKeyPressed()
//{
//	return m_keyboardState;
//}

bool DX11InputManager::GetKeyPressed(int key)
{
	//if (m_currentKey == key)
	//{
	//	return false;
	//}
	//else
	//{
	//	m_currentKey = key;
	//}

	if (m_keyboardState[key] & 0x80)
	{
		return true;
	}
	else
	{
		return false;
	}

	return (m_keyboardState[key] & 0x80);
	m_timer += TheTimer::Instance()->GetDt();
	if (m_timer > m_pollRate)
	{
		m_timer = 0.0f;
		return (m_keyboardState[key] & 0x80);
	}

	return false;

	if (m_keyboardState[key] & 0x80)
	{
		if (m_currentKey == key)
		{
			return false;
		}
		else
		{
			m_currentKey = key;
			return true;
		}
	}
	else
	{
		return false;
	}
}

DIMOUSESTATE& DX11InputManager::GetMouseState()
{
	return m_mouseState;
}

bool DX11InputManager::GetTakingInput()
{
	return m_takingKeyboardInput;
}

void DX11InputManager::SetTakingInput(bool b)
{
	m_takingKeyboardInput = b;
}